"""
1. 总结笔记
    重难点：
    1）.什么是单例模式
        面试官问什么是单例模式时，千万不要答非所问，给出单例模式有两种类型之类的回答，要围绕单例模式的定义去展开。
        单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时，为了防止频繁地创建对象使得内存飙升，单例模式可以让程序仅在内存中创建一个对象，让所有需要调用的地方都共享这一单例对象。

        单例模式有两种类型：
            懒汉式：在真正需要使用对象时才去创建该单例类对象
            饿汉式：在类加载时已经创建好该单例对象，等待被程序使用

        https://blog.csdn.net/qq_42773863/article/details/107367391

    2）. 什么是装饰器，带参数的装饰器的调用过程
        1.把一个函数当作参数，返回一个替代版的函数，本质上就是一个返回函数的函数
        2.可以在不改变原函数的基础上，给函数增加功能。

        用于返回wrapper（不带（）表示返回函数，带（）表示返回运行结果）


    3）__new__和__init__的区别和联系
    4）super是什么
2.实现一个类，前5次创建对象，以后创建返回5个中随机的一个
"""
import random


class MyClass(object):
    objs = []

    def __new__(cls, *args, **kwargs):
        if len(cls.objs) < 5:
            obj = super().__new__(cls)  # MyClass创建一个对象
            cls.objs.append(obj)
        else:
            obj = random.choice(cls.objs)
        return obj


class Person(object):
    def __init__(self, firstname, lastname):
        self.firstname = firstname
        self.lastname = lastname

    def fullname(self):
        print(f'{self.firstname} {self.lastname}')


class Student(Person):
    def __init__(self, firstname, lastname, grade):
        self.grade = grade
        # 初始化父类
        # Person.__init__(self, firstname, lastname)
        super(Student, self).__init__(firstname, lastname)
        super().__init__(firstname, lastname)

    def show_student(self):
        Person.fullname(self)
        print('Grade', self.grade)


if __name__ == '__main__':
    stu = Student('Tom', 'Then', '第五课')
    stu.show_student()


class A(object):
    def __init__(self):
        super(A, self).__init__()
        print("A~~~~~")


class B(object):
    def __init__(self):
        super(B, self).__init__()
        print("B~~~~~")


class C(A, B):
    def __init__(self):
        super(C, self).__init__()
        print("C~~~~~")


c = C()
